package net.xyzmc.pokemonbroadcast.bukkit;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import com.pixelmonmod.pixelmon.Pixelmon;
import com.pixelmonmod.pixelmon.api.overlay.notice.EnumOverlayLayout;
import com.pixelmonmod.pixelmon.api.overlay.notice.NoticeOverlay;
import com.pixelmonmod.pixelmon.api.pokemon.PokemonSpec;
import com.pixelmonmod.pixelmon.comm.packetHandlers.custom.overlays.CustomNoticePacket;
import me.clip.placeholderapi.PlaceholderAPI;
import net.minecraft.server.MinecraftServer;
import net.xyzmc.pokemonbroadcast.bukkit.commands.PokemonBroadcastCommand;
import net.xyzmc.pokemonbroadcast.bukkit.commands.Reload;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.bukkit.scheduler.BukkitRunnable;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.*;

public class Main extends JavaPlugin implements PluginMessageListener {

    public final static Queue<PokemonBroadcast> queue = new LinkedList<>();
    public final static List<PokemonBroadcast> broadcast = new LinkedList<>();
    public final static List<String> messages = new ArrayList<>();
    public static Main instance;
    private static boolean b = true;
    private static String mode = "random";
    private static boolean state = true;

    static boolean placeholderAPI = false;


    @Override
    public void onEnable() {
        instance = this;
        if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
            placeholderAPI = true;
        }
        init();
        this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
        this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", this);
        Bukkit.getPluginCommand("pokemonbroadcast").setExecutor(new PokemonBroadcastCommand());
        Bukkit.getPluginCommand("pokebcreload").setExecutor(new Reload());
        Bukkit.getPluginCommand("pokemonbroadcast").setTabCompleter(new PokemonBroadcastCommand());
        run();
        this.getLogger().info("PokemonBroadcast enabled!");
    }

    //检测宝可梦mod是否存在


    @Override
    public void onDisable() {
        this.getServer().getMessenger().unregisterOutgoingPluginChannel(this);
        this.getServer().getMessenger().unregisterIncomingPluginChannel(this);
        this.getLogger().info("PokemonBroadcast disabled!");
    }

    public void init() {
        saveDefaultConfig();
        reloadConfig();
        state = getConfig().getBoolean("state");
        mode = getConfig().getString("mode");
        broadcast.clear();
        for (String s : getConfig().getConfigurationSection("broadcast").getKeys(false)) {
            String pokeName = getConfig().getString("broadcast." + s + ".pokeName");
            boolean isShiny = getConfig().getBoolean("broadcast." + s + ".shiny");
            int time = getConfig().getInt("broadcast." + s + ".time");
            String[] messages = getConfig().getString("broadcast." + s + ".message").split(" ");
            PokemonSpec pokemonSpec = PokemonSpec.from(pokeName + " " + (isShiny ? "s" : "!s"));
            broadcast.add(new PokemonBroadcast(pokemonSpec, time, messages));
        }
        getLogger().info("广播信息已加载!");
    }

    private void run() {
        new BukkitRunnable() {
            @Override
            public void run() {
                if (b) {
                    if(queue.size() > 0) {
                        b = false;
                        PokemonBroadcast q = queue.poll();
                        q.runBroadcast();
                    }else {
                        if(state && broadcast.size() > 0){
                            b = false;
                            if(mode.equals("random")){
                                PokemonBroadcast q = broadcast.get(new Random().nextInt(broadcast.size()));
                                q.runBroadcast();
                            }else {
                                PokemonBroadcast q = broadcast.get(0);
                                q.runBroadcast();
                                //从broadcast 删除q 并将q添加到broadcast的最后
                                PokemonBroadcast q1 = q.clone();
                                broadcast.remove(q);
                                broadcast.add(q1);
                            }
                        }
                    }
                }
            }
        }.runTaskTimerAsynchronously(this, 100, 20);
    }

    @Override
    public void onPluginMessageReceived(String channel, Player player, byte[] message) {
        if (!channel.equals("BungeeCord")) {
            return;
        }
        ByteArrayDataInput in = ByteStreams.newDataInput(message);
        String subchannel = in.readUTF();
        if (subchannel.equals("PokeBroadcast")) {
            short len = in.readShort();
            byte[] msgbytes = new byte[len];
            in.readFully(msgbytes);
            DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
            try {
                String somedata = msgin.readUTF();
                if (!messages.contains(somedata)) {
                    String[] data = somedata.split(" ");
                    String pokename = data[0];
                    String Shiny = data[1];
                    int time = Integer.parseInt(data[2]);
                    String[] msg = new String[data.length - 3];
                    System.arraycopy(data, 3, msg, 0, data.length - 3);
                    PokemonSpec spec = new PokemonSpec(pokename + " " + Shiny);
                    queue.offer(new PokemonBroadcast(spec, time, msg));
                } else {
                    messages.remove(somedata);
                }
            } catch (IOException ignored) {
            }
        }
    }

    public static class PokemonBroadcast implements Cloneable{
        private final PokemonSpec ps;
        private final int time;
        private final String[] broadcast;

        public PokemonBroadcast(PokemonSpec ps, int time, String[] broadcast) {
            this.ps = ps;
            this.time = time;
            this.broadcast = broadcast;
        }

        public void runBroadcast() {
            //循环全服在线玩家
            MinecraftServer.getServerInst().server.getOnlinePlayers().forEach(p -> {
                for (int i = 0; i < broadcast.length; i++) {
                    broadcast[i] = broadcast[i].replaceAll("&", "§");
                    if(placeholderAPI){
                        broadcast[i] = PlaceholderAPI.setPlaceholders(p,broadcast[i]);
                    }
                }
                CustomNoticePacket nb = NoticeOverlay.builder()
                        .setLines(broadcast)
                        .setPokemonSprite(ps)
                        .setLayout(EnumOverlayLayout.LEFT_AND_RIGHT)
                        .build();
                Pixelmon.network.sendTo(nb, p.getHandle());
            });
//            Bukkit.getOnlinePlayers().forEach(player -> Pixelmon.network.sendTo(nb, ((CraftPlayer) player).getHandle()));
            new BukkitRunnable() {
                @Override
                public void run() {
                    MinecraftServer.getServerInst().server.getOnlinePlayers().forEach(p -> NoticeOverlay.hide(p.getHandle()));
                    //循环全服在线玩家
//                    Bukkit.getOnlinePlayers().forEach(player -> NoticeOverlay.hide(((CraftPlayer) player).getHandle()));
                    b = true;
                }
            }.runTaskLater(Main.instance, time * 20L);
        }

        //重写clone方法
        @Override
        public PokemonBroadcast clone() {
            return new PokemonBroadcast(ps, time, broadcast);
        }
    }
}